"""
本程序根据https://www.boxentriq.com/code-breaking/baudot-code
提供的BaudoutCode对照表编写，使用码表为 Original Baudot code
作者：林政慷
"""

"""这是实现Baudout编译码器的核心代码"""


class Baudot:
    def __init__(self):
        self.raw2Baudot_letter = {
            '': '00000', 'A': '00001', 'B': '01100', 'C': '01101',
            'D': '01111', 'E': '00010', 'F': '01110', 'G': '01010',
            'H': '01011', 'I': '00110', 'J': '01001', 'K': '11001',
            'L': '11011', 'M': '11010', 'N': '11110', 'O': '00111',
            'P': '11111', 'Q': '11101', 'R': '11100', 'S': '10100',
            'T': '10101', 'U': '00101', 'V': '10111', 'W': '10110',
            'X': '10010', 'Y': '00100', 'Z': '10011', '\r': '00011',
            ' ': '10000', '\n': '10001'}

        self.raw2Baudot_figure = {
            '': '00000', '0': '01111', '1': '00001', '2': '00010',
            '3': '00100', '4': '00101', '5': '00111', '6': '01001',
            '7': '01010', '8': '01100', '9': '01101', '+': '01011',
            '-': '11100', '（': '11001', ')': '11010', '=': '11011',
            '%': '11111', '/': '11101', '.': '10100', '\'': '10111',
            ':': '10011', ',': '10010', '?': '10110', '\r': '00011',
            ' ': '01000', '\n': '10001'}

        self.Baudot2raw_letter = dict(zip(self.raw2Baudot_letter.values(), self.raw2Baudot_letter.keys()))
        self.Baudot2raw_figure = dict(zip(self.raw2Baudot_figure.values(), self.raw2Baudot_figure.keys()))

    def coding(self, mod, raw_str):
        f = 0
        letter = self.raw2Baudot_letter.keys()
        figure = self.raw2Baudot_figure.keys()
        if mod == 0:
            out = []
            for i in raw_str:
                i = i.upper()
                if i in letter:
                    if f == 0:
                        out.append(self.raw2Baudot_letter[i])
                    else:
                        out.append('10000')
                        out.append(self.raw2Baudot_letter[i])
                        f = 0
                elif i in figure:
                    if f == 1:
                        out.append(self.raw2Baudot_figure[i])
                    else:
                        out.append('01000')
                        out.append(self.raw2Baudot_figure[i])
                        f = 1
                else:
                    return "非法的输入"
            out = ' '.join(out)
        elif mod == 1:
            raw_str = list(filter(lambda n: bool(n == '0' or n == '1'), raw_str))
            rese = ['00110', '01110', '10101', '11110']  # 保留字的BaudoutCode
            if len(raw_str) % 5 != 0:
                return "Baudout码长度错误，码元由五个比特构成"
            raw_str = ''.join(raw_str)
            f = 0
            out = []
            for i in range(0, (len(raw_str) // 5)):
                code = raw_str[5 * i: 5 * (i + 1)]
                if (f == 1) and (code == '10000'):
                    f = 0
                elif (f == 0) and (code == '01000'):
                    f = 1
                elif (code == '11000'):
                    # del实现
                    if out:
                        del (out[-1])
                    else:
                        pass
                elif (f == 1) and (code in rese):
                    out.append('')
                else:
                    if f == 0: out.append(self.Baudot2raw_letter[code])
                    if f == 1: out.append(self.Baudot2raw_figure[code])
            out = ''.join(out)
        return out


"""以下所有代码都只是为了实现图形化界面"""
"""UI作者：林政慷"""
import os

try:
    from PyQt5 import QtCore, QtGui, QtWidgets
    from PyQt5.QtWidgets import QMainWindow, QApplication
except ModuleNotFoundError:
    os.system("pip install PyQt5")
    from PyQt5 import QtCore, QtGui, QtWidgets
    from PyQt5.QtWidgets import QMainWindow, QApplication
else:
    from PyQt5 import QtCore, QtGui, QtWidgets
    from PyQt5.QtWidgets import QMainWindow, QApplication
"""因为用到第三方库，自动检测环境是否安装，安装则导入，若无则安装"""


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(658, 434)
        MainWindow.setStyleSheet("QWiget{\n"
                                 "    color: rgb(255, 255, 255);\n"
                                 "}")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.decoding = QtWidgets.QPushButton(self.centralwidget)
        self.decoding.setMinimumSize(QtCore.QSize(0, 40))
        font = QtGui.QFont()
        font.setFamily("仿宋")
        font.setPointSize(15)
        self.decoding.setFont(font)
        self.decoding.setObjectName("decoding")
        self.gridLayout.addWidget(self.decoding, 3, 7, 1, 1)
        spacerItem = QtWidgets.QSpacerItem(10, 40, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem, 1, 0, 1, 1)
        spacerItem1 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
        self.gridLayout.addItem(spacerItem1, 4, 7, 1, 1)
        spacerItem2 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem2, 2, 2, 1, 1)
        spacerItem3 = QtWidgets.QSpacerItem(10, 40, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem3, 1, 8, 1, 1)
        spacerItem4 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem4, 0, 7, 1, 1)
        spacerItem5 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem5, 0, 2, 1, 1)
        self.coding = QtWidgets.QPushButton(self.centralwidget)
        self.coding.setMinimumSize(QtCore.QSize(0, 40))
        font = QtGui.QFont()
        font.setFamily("仿宋")
        font.setPointSize(15)
        self.coding.setFont(font)
        self.coding.setObjectName("coding")
        self.gridLayout.addWidget(self.coding, 3, 2, 1, 1)
        spacerItem6 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem6, 2, 7, 1, 1)
        spacerItem7 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
        self.gridLayout.addItem(spacerItem7, 4, 2, 1, 1)
        spacerItem8 = QtWidgets.QSpacerItem(10, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem8, 1, 4, 1, 1)
        self.code_str = QtWidgets.QPlainTextEdit(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Times New Roman")
        font.setPointSize(15)
        font.setBold(True)
        font.setItalic(True)
        font.setWeight(75)
        self.code_str.setFont(font)
        self.code_str.setObjectName("code_str")
        self.gridLayout.addWidget(self.code_str, 1, 7, 1, 1)
        self.raw_str = QtWidgets.QPlainTextEdit(self.centralwidget)
        font = QtGui.QFont()
        font.setFamily("Times New Roman")
        font.setPointSize(15)
        font.setBold(True)
        font.setItalic(True)
        font.setWeight(75)
        self.raw_str.setFont(font)
        self.raw_str.setObjectName("raw_str")
        self.gridLayout.addWidget(self.raw_str, 1, 2, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.decoding.setText(_translate("MainWindow", "译   码"))
        self.coding.setText(_translate("MainWindow", "编   码"))
        self.code_str.setPlaceholderText(_translate("MainWindow", "请在此输入要进行译码的Baudout码"))
        self.raw_str.setPlaceholderText(_translate("MainWindow", "请在此处输入要进行编码的文本"))


class Win_code(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(Win_code, self).__init__(parent)
        self.setupUi(self)
        self.setWindowTitle("Baudout编译码器")
        self.b = Baudot()
        self.button()

    def button(self):
        self.coding.clicked.connect(self.cod)
        self.decoding.clicked.connect(self.decod)

    def cod(self):
        self.Decode_str = self.raw_str.toPlainText()
        if self.Decode_str:
            out = self.b.coding(0, self.Decode_str)
            self.code_str.setPlainText(out)
        else:
            pass

    def decod(self):
        self.Code_str = self.code_str.toPlainText()
        if self.Code_str:
            out = self.b.coding(1, self.Code_str)
            self.raw_str.setPlainText(out)
        else:
            pass


from sys import argv, exit

app = QApplication(argv)
Win = Win_code()
Win.show()
exit(app.exec_())